<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class Model_transaksi extends CI_Model {

    function __construct() {
        parent::__construct();
    }

    // Main Logic saat terjadi inputan member baru    
    public function add_new_member($no_hp, $nickname, $id_upline, $email, $pin, $pin_asli) {
        // 1. Memasukkan ke data member. Dibedakan antara member yang memiliki upline atau member yang tidak memiliki upline
        if ($id_upline) {
            $alias_upline = $this->db->query("select alias_member from member where id_member = ? ", array($id_upline))->row()->alias_member;
            $this->db->query("insert into member(pin,no_hp,nickname,upline,alias_upline) values(?,?,?,?,?)", array($pin, $no_hp, $nickname, $id_upline, $alias_upline));

            $id_member = $this->db->insert_id();
            $this->db->query("insert into status_map(upline,downline) values(?,?)", array($id_upline, $id_member));
        } else {
            $this->db->query("insert into member(pin,no_hp,nickname) values(?,?,?)", array($pin, $no_hp, $nickname));
            $id_member = $this->db->insert_id();
        }        

        // 2. Alias member digenerate berdasarkan ID nya, jadi bisa dipastikan tidak ada yang memiliki alias berbeda
        $alias_member = "M7" . str_pad($id_member, 4, "0", STR_PAD_LEFT);
        $this->db->query("update member set alias_member = ?, date_active=?, email=? where id_member =?", array($alias_member, date("Y-m-d", strtotime("today")), $email, $id_member));
        $this->kirim_sms_aktifasi($alias_member, $pin_asli, $no_hp);

        // 3. Mendaftarkan member ke dalam board starter
        $sql = "insert into board_member_starter(id_member,alias_member) values(?,?)";
        $this->db->query($sql, array($id_member, $alias_member));
        $count = $this->db->query("select id_member as jumlah from board_member_starter where id_member = ? ", array($id_upline))->num_rows();
        if ($count && $id_upline) {
            $data = array();

            // 4. Mendaftarkan member ke uplinenya
            $this->add_node_recursive($id_member, $id_upline, $data);
        }

        // 5. Mendaftarkan member ke Up-Upline
        $up_upline = $this->db->query("select upline from member where id_member = ? ", array($id_upline))->row()->upline;
        if ($up_upline) {
            $this->add_node_in_board($id_member, $up_upline, $id_upline);
        }

        // 6. Menambahkan poin untuk member dan uplinenya
        $this->add_poin($id_member, 0, "Registrasi Baru", 100);
        if ($id_upline) {
            $this->add_poin($id_upline, 0, "Sponsor downline baru : " . $alias_member, 100);
        }
        return $alias_member;
    }

    // Fungsi untuk menambahkan poin member
    // [optimasi] fungsi update poin sebaiknya dilakukan di trigger
    public function add_poin($id_member, $id_transaksi, $keterangan, $penambahan = 0, $pengurangan = 0) {
        $last_poin = $this->db->query("select poin_balance from member where id_member = ?", array($id_member))->row()->poin_balance;
        $alias_member = $this->db->query("select alias_member from member where id_member = ?", array($id_member))->row()->alias_member;
        $current_poin = $last_poin + $penambahan - $pengurangan;
        $this->db->query("insert into mutasi_poin(keterangan, id_member,alias_member,last_poin,penambahan,pengurangan,current_poin) values (?,?,?,?,?,?,?)", array($keterangan, $id_member, $alias_member, $last_poin, $penambahan, $pengurangan, $current_poin));
        $this->db->query("update member set poin_balance=? where id_member=?", array($current_poin, $id_member));
    }

    // Fungsi ini bertugas untuk mendaftarkan suatu ID ke Suatu Board member Starter
    public function add_node_in_board($id_member, $up_upline, $upline) {
        $tipe_board = 'starter';
//        echo $tipe_board . ": " . $id_member . " mempengaruhi " . $up_upline . " karena " . $upline . "<br/>";
        $node_empty_index = $this->db->query("select node_empty_index from board_member_" . $tipe_board . " where node_empty_count > 0 and id_member = ?", array($up_upline))->row()->node_empty_index;
        if ($node_empty_index) {
            $query = $this->db->query("select * from board_member_" . $tipe_board . " where node_empty_count > 0 and id_member = ?", array($up_upline));
            $rArrayTemp = $query->result_array();
            foreach ($rArrayTemp as $rArray) {
                for ($position = 1; $position <= 6; $position++) {
                    if ($rArray["node_" . $position] == $upline) {
                        if ($position === 1) {
                            if ($node_empty_index == 3) {
                                $this->db->query("update board_member_" . $tipe_board . " set node_empty_index = node_empty_index + 1, node_empty_count = node_empty_count -1, node_3 = ? where id_member = ?", array($id_member, $up_upline));
                            } else if ($node_empty_index == 4) {
                                $this->db->query("update board_member_" . $tipe_board . " set node_empty_index = node_empty_index + 1, node_empty_count = node_empty_count -1, node_4 = ? where id_member = ?", array($id_member, $up_upline));
                            }
                        } else if ($position === 2) {
                            if ($node_empty_index == 5) {
                                $this->db->query("update board_member_" . $tipe_board . " set node_empty_index = node_empty_index + 1, node_empty_count = node_empty_count -1, node_5 = ? where id_member = ?", array($id_member, $up_upline));
                            } else if ($node_empty_index == 6) {
                                $this->db->query("update board_member_" . $tipe_board . " set node_empty_index = node_empty_index + 1, node_empty_count = node_empty_count -1, node_6 = ? where id_member = ?", array($id_member, $up_upline));
                                $this->completing_board($up_upline);
                            }
                        }
                        break;
                    }
                }
            }
        }
    }

    // Fungsi ini bertugas untuk mendaftarkan suatu ID ke Suatu Board member Expert    
    public function add_node_in_board_expert($id_member, $up_upline, $upline) {
        $tipe_board = 'expert';
//        echo $tipe_board . ": " . $id_member . " mempengaruhi " . $up_upline . " karena " . $upline . "<br/>";
        $node_empty_index = $this->db->query("select node_empty_index from board_member_" . $tipe_board . " where id_member = ?", array($up_upline))->row()->node_empty_index;
        if ($node_empty_index) {
            $query = $this->db->query("select * from board_member_" . $tipe_board . " where id_member = ?", array($up_upline));
            $rArrayTemp = $query->result_array();
            foreach ($rArrayTemp as $rArray) {
                for ($position = 1; $position <= 6; $position++) {
                    if ($rArray["node_" . $position] == $upline) {
                        if ($position === 1) {
                            if ($node_empty_index == 3) {
                                $this->db->query("update board_member_" . $tipe_board . " set node_empty_index = node_empty_index + 1, node_empty_count = node_empty_count -1, node_3 = ? where id_member = ?", array($id_member, $up_upline));
                            } else if ($node_empty_index == 4) {
                                $this->db->query("update board_member_" . $tipe_board . " set node_empty_index = node_empty_index + 1, node_empty_count = node_empty_count -1, node_4 = ? where id_member = ?", array($id_member, $up_upline));
                            }
                        } else if ($position === 2) {
                            if ($node_empty_index == 5) {
                                $this->db->query("update board_member_" . $tipe_board . " set node_empty_index = node_empty_index + 1, node_empty_count = node_empty_count -1, node_5 = ? where id_member = ?", array($id_member, $up_upline));
                            } else if ($node_empty_index == 6) {
                                $this->add_poin($up_upline, 0, "Fly di Board Expert", 5000);
                                $this->db->query("update board_member_expert set node_1=0,node_2=0,node_3=0,node_4=0,node_5=0,node_6=0, node_empty_index = 1, node_empty_count = 6 where id_member = ?", array($up_upline));
                            }
                        }
                        break;
                    }
                }
            }
        }
        $up_upline = $this->db->query("select upline from member where id_member = ?", array($up_upline))->row()->upline;
        if ($up_upline) {
            $this->add_node_in_board_expert($id_member, $up_upline, $upline);
        }
    }

    // Fungsi ini bertugas untuk mendaftarkan suatu ID ke Suatu Board member starter. 
    // Perbedaan dengan fungsi add board biasa, fungsi ini akan terus mencari sampai kedalaman yang tidak terbatas, agar member bisa terdaftar di upline
    private function add_node_recursive($new_member, $current_board, &$next_check, $iCheck = 0) {
        $node_empty_index = $this->db->query("select node_empty_index from board_member_starter where node_empty_count > 0 and id_member = ?", array($current_board))->row()->node_empty_index;
        if ($node_empty_index) {
            $this->db->query("update board_member_starter set node_empty_index = node_empty_index + 1, node_empty_count = node_empty_count -1, node_" . $node_empty_index . " = ? where id_member = ?", array($new_member, $current_board));
            $this->completing_board($current_board);
        } else {
            // add left_child & right_child dari 
            $query = $this->db->query("select node_1, node_2 from board_member_starter where id_member = ?", array($current_board));
            $result = $query->result();
            foreach ($result as $data) {
                $next_check[] = $data->node_1;
                $next_check[] = $data->node_2;
            }
            $this->add_node_recursive($new_member, $next_check[$iCheck], $next_check, ++$iCheck);
        }
    }

    // Fungsi ini bertugas untuk mengecek jika suatu board telah "penuh"
    public function completing_board($id_member) {
        $node_empty_index = $this->db->query("select node_empty_index from board_member_starter where id_member = ?", array($id_member))->row()->node_empty_index;

        // jika di starter board dia sudah penuh
        if ($node_empty_index == 7) {

            $this->add_poin($id_member, 0, "Fly dari Board Stater", 500);
            $this->db->query("update member set level=1 where id_member=?", array($id_member));
            $alias_member = $this->db->query("select alias_member from member where id_member = ?", array($id_member))->row()->alias_member;
            $this->db->query("insert into log_perubahan_level(id_member,alias_member,current_status) values (?,?,?) ",array($id_member, $alias_member, 1));
            $this->completing_level_poin($id_member);
            // masukkan ke expert board jika belum punya
            $node_empty_index = $this->db->query("select node_empty_index from board_member_expert where id_member = ?", array($id_member))->num_rows();
            if (!$node_empty_index) {
                $alias_member = $this->db->query("select alias_member from member where id_member = ? ", array($id_member))->row()->alias_member;
                $sql = "insert into board_member_expert(id_member,alias_member) values(?,?)";
                $this->db->query($sql, array($id_member, $alias_member));
            }

            // cek ke upline, apakah memiliki expert_board
            $up_upline = $this->db->query("select upline from member where id_member = ?", array($id_member))->row()->upline;
            if ($up_upline) {
                $node_empty_index = $this->db->query("select node_empty_index from board_member_expert where id_member = ?", array($up_upline))->row()->node_empty_index;                
                if ($node_empty_index) {
                    $this->db->query("update board_member_expert set node_empty_index = node_empty_index + 1, node_empty_count = node_empty_count - 1, node_" . $node_empty_index . " = ? where id_member = ?", array($id_member, $up_upline));
                    $node_empty_index = $this->db->query("select node_empty_index from board_member_expert where id_member = ?", array($up_upline))->row()->node_empty_index;
                    if ($node_empty_index == 7) {
                        $this->add_poin($up_upline, 0, "Fly di Board Expert", 5000);
                        $this->db->query("update board_member_expert set node_1=0,node_2=0,node_3=0,node_4=0,node_5=0,node_6=0, node_empty_index = 1, node_empty_count = 6 where id_member = ?", array($up_upline));
                    }

                    // add ke up_upline
                    $up_up_upline = $this->db->query("select upline from member where id_member = ?", array($up_upline))->row()->upline;
                    if ($up_up_upline) {
                        $this->add_node_in_board_expert($id_member, $up_up_upline, $up_upline);
                    }
                } else {                    
                    add_node_recursive($id_member, $up_upline);
                }
            }
        }
    }

    function completing_level_poin($id_member) {
        $map_poin = array(
            array(0, 0, 0), // index kosong saja agar pas dengan perhitungan level
            array(50, 25, 10),
            array(100, 50, 25),
            array(200, 100, 50),
            array(400, 200, 10)
        );
        $arr_level = array(
            'starter', 'silver_eagle', 'gold_eagle', 'diamond', 'crown_diamond'
        );

        $upline_1 = $this->db->query("select upline from member where id_member = ?", array($id_member))->row()->upline;
        $level = $this->db->query("select level from member where id_member = ?", array($id_member))->row()->level;
                
        if ($level > 4) {
            $level = 4;
        } else if ($level == 0){            
            return null;
        }

        if ($upline_1) {
            $level_name = str_replace("_", " ", strtoupper($arr_level[$level]));
            $alias_member = $this->db->query("select alias_member from member where id_member = ?", array($id_member))->row()->alias_member;
            $jumlah_poin = $map_poin[$level][0];
            $this->add_poin($upline_1, 0, "Bonus Kenaikan Level Downline " . $alias_member . " ke " . $level_name, $jumlah_poin);

            $upline_2 = $this->db->query("select upline from member where id_member = ?", array($upline_1))->row()->upline;
            if ($upline_2) {
                $jumlah_poin = $map_poin[$level][1];
                $this->add_poin($upline_2, 0, "Bonus Kenaikan Level Downline " . $alias_member . " ke " . $level_name, $jumlah_poin);

                $upline_3 = $this->db->query("select upline from member where id_member = ?", array($upline_2))->row()->upline;
                if ($upline_3) {
                    $jumlah_poin = $map_poin[$level][2];
                    $this->add_poin($upline_3, 0, "Bonus Kenaikan Level Downline " . $alias_member . " ke " . $level_name, $jumlah_poin);
                }
            }
        }
        $this->update_reveral($id_member, $arr_level[$level]);
    }

    function update_reveral($id_member, $level) {       
        $upline = $this->db->query("select upline from member where id_member = ?", array($id_member))->row()->upline;        
        if ($upline) {
            $this->db->query("update status_map set is_$level = 1 where upline = ? and downline = ?", array($upline, $id_member));
            $jumlah = $this->db->query("select count(*) as jumlah from status_map where upline = ? and is_$level = 1",array($upline))->row()->jumlah;
            
            if ($jumlah >= 6) {
                $this->db->query("update member set level = level + 1 where id_member = ?",array($upline));
                
                $alias_member = $this->db->query("select alias_member from member where id_member = ?", array($upline))->row()->alias_member;
                $level = $this->db->query("select level from member where id_member = ?", array($upline))->row()->level;
                $this->db->query("insert into log_perubahan_level(id_member,alias_member,current_status) values (?,?,?) ",array($upline, $alias_member, $level));
            
                $this->completing_level_poin($upline);
            }
            $upline = $this->db->query("select upline from member where id_member = ?", array($upline))->row()->upline;
            if ($upline){
                $this->update_reveral($upline, $level);
            }
        }
    }

    // fungsi ini digunakan untuk melakukan filter saat user melakukan klik update lebih dari 1kali
    public function cek_double_update($id_request) {
        $last_status = $this->db->query("select is_approved from request_daftar where id_request = ?", array($id_request))->row()->is_approved;
        return $last_status;
    }
    

    // registrasi via menu admin dihitung sebagai transaksi, karena melibatkan pertukaran uang tunai dengan id baru
    public function insert_transaksi($post_data) {
        $data = $this->db->query("select harga_beli,harga_jual from harga_produk where id_produk=?", array('AKTIF'))->row();
        $post_data[] = $data->harga_beli;
        $post_data[] = $data->harga_jual;
        $post_data[] = date("Y-m-d", strtotime("today"));
        $post_data[] = date("H:i:s", strtotime("now"));
        $this->db->query("insert into transaksi"
                . "(id_member,alias_member,produk,data_1,data_2,data_3,status,harga_beli,harga_jual,jumlah_beli,tanggal_transaksi,waktu_transaksi) values "
                . "(?,?,?,?,?,?,?,?,?,1,?,?) ", $post_data);
        return $this->db->insert_id();
    }

    // Saat request daftar diterima, maka data pendaftaran harus diupdate
    public function update_data_pendaftaran($id_request, $id_request_pin, $is_approved) {
        $this->db->query("update request_daftar set date_activated=now(),id_request_pin=?,is_approved=? where id_request=?", array($id_request_pin, $is_approved, $id_request));
    }

    // Digunakan untuk mencari alias upline karena yang masuk hanya id upline saja
    // [optimasi] bisa dilakukan melalui trigger, atau mendapatkan dari value input hidden
    public function update_alias_upline($id_request, $upline_id) {
        $alias_member = $this->db->query("select alias_member from member where id_member=?", array($upline_id))->row()->alias_member;
        $this->db->query("update request_daftar set alias_member=? where id_request=?", array($alias_member, $id_request));
    }

    

    public function kirim_sms_aktifasi($id_member, $pin, $hp) {
        $isi_pesan = "Selamat, keanggotaan anda telah aktif. Silahkan login menggunakan ID : $id_member, PIN : $pin. Selamat bergabung & Salam Sukses (M7Holidays)";
        $penerima = $hp;
        $kombinasi_pesan = "$isi_pesan|$hp|" . microtime(true);

        $data_encrypted = base64_encode($kombinasi_pesan);
        $temp = $data_encrypted[7];
        $data_encrypted[7] = $data_encrypted[17];
        $data_encrypted[17] = $temp;

        _postValueWithTimeOut("http://www.belanjasms.com/index.php/eksternal_interface/m7h_interfaces", $data_encrypted);
//        _postValueWithTimeOut("http://localhost/belanjasms/index.php/eksternal_interface/m7h_interfaces", $data_encrypted);
    }   
    
}
